package app.error.handler;

import com.dj.common.response.ApiResponse;
import com.dj.gateway.app.error.GatewayError;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.autoconfigure.web.ResourceProperties;
import org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler;
import org.springframework.boot.web.reactive.error.ErrorAttributes;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.*;
import reactor.core.publisher.Mono;

import java.util.Map;

public class JsonErrorWebExceptionHandler extends DefaultErrorWebExceptionHandler {

	@Autowired
    private GatewayHandlerExceptionAdvice gatewayHandlerExceptionAdvice;
	
	
	public JsonErrorWebExceptionHandler(ErrorAttributes errorAttributes, ResourceProperties resourceProperties,
			ErrorProperties errorProperties, ApplicationContext applicationContext) {
		super(errorAttributes, resourceProperties, errorProperties, applicationContext);
	}

	/**
	 * 指定响应处理方法为JSON处理的方法
	 * 
	 * @param errorAttributes
	 */
	@Override
	protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
		return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
	}

    /**
     * 根据code获取对应的HttpStatus
     * @param errorAttributes
     */
    @Override
    protected int getHttpStatus(Map<String, Object> errorAttributes) {
        Integer httpStatus = (Integer) errorAttributes.remove("httpStatus");
        return httpStatus != null ? httpStatus : HttpStatus.INTERNAL_SERVER_ERROR.value();
    }
	
    @Override
	protected Mono<ServerResponse> renderErrorResponse(ServerRequest request) {
		Throwable throwable = getError(request);
		GatewayError getewayError = gatewayHandlerExceptionAdvice.handle(throwable);
		return ServerResponse.status(getewayError.getStatus())
				.contentType(MediaType.APPLICATION_JSON)
				.body(BodyInserters.fromValue(ApiResponse.fail(getewayError.getCode(), getewayError.getMsg())));
	}
}
